package com.wngbms.cacheline;

import java.util.concurrent.CountDownLatch;

public class CacheLineTest {

    public static void main(String[] args) throws InterruptedException {
//        m();
//        testC();
        testVC();
//        testPC();
        testPVC();
    }

    /**
     * 28 2480 6500
     * 2835854500
     * 2749596900
     * @throws InterruptedException
     */
    public static void testPVC() throws InterruptedException {
        PVC c = new PVC();

        CountDownLatch countDownLatch = new CountDownLatch(2);
        long start = System.nanoTime();

        new Thread(() -> {
            for (long k = 0; k < 500L * 1000L * 1000L; k++) {
                c.i++;
            }
            countDownLatch.countDown();
        }).start();

        new Thread(() -> {
            for (long k = 0; k < 500L * 1000L * 1000L; k++) {
                c.j++;
            }
            countDownLatch.countDown();
        }).start();

        countDownLatch.await();
        System.out.println(System.nanoTime() - start);
    }

    /**
     * 1 9593 5200
     * 206242800
     * 193277200
     * 228822700
     * @throws InterruptedException
     */
    public static void testPC() throws InterruptedException {
        PC c = new PC();

        CountDownLatch countDownLatch = new CountDownLatch(2);
        long start = System.nanoTime();

        new Thread(() -> {
            for (long k = 0; k < 500L * 1000L * 1000L; k++) {
                c.i++;
            }
            countDownLatch.countDown();
        }).start();

        new Thread(() -> {
            for (long k = 0; k < 500L * 1000L * 1000L; k++) {
                c.j++;
            }
            countDownLatch.countDown();
        }).start();

        countDownLatch.await();
        System.out.println(System.nanoTime() - start);
    }

    /**
     * 最慢
     * 157 6906 7400
     * 16069492600
     * @throws InterruptedException
     */
    public static void testVC() throws InterruptedException {
        VC c = new VC();

        CountDownLatch countDownLatch = new CountDownLatch(2);
        long start = System.nanoTime();

        new Thread(() -> {
            for (long k = 0; k < 500L * 1000L * 1000L; k++) {
                c.i++;
            }
            countDownLatch.countDown();
        }).start();

        new Thread(() -> {
            for (long k = 0; k < 500L * 1000L * 1000L; k++) {
                c.j++;
            }
            countDownLatch.countDown();
        }).start();

        countDownLatch.await();
        System.out.println(System.nanoTime() - start);
    }

    /**
     * 1 9083 8900
     * 225775200
     * 226091600
     * 193375800
     * @throws InterruptedException
     */
    public static void testC() throws InterruptedException {
        C c = new C();

        CountDownLatch countDownLatch = new CountDownLatch(2);
        long start = System.nanoTime();

        new Thread(() -> {
            for (long k = 0; k < 500L * 1000L * 1000L; k++) {
                c.i++;
            }
            countDownLatch.countDown();
        }).start();

        new Thread(() -> {
            for (long k = 0; k < 500L * 1000L * 1000L; k++) {
                c.j++;
            }
            countDownLatch.countDown();
        }).start();

        countDownLatch.await();
        System.out.println(System.nanoTime() - start);
    }

    public static class C {
        public long i, j;
    }

    public static class VC {
        public volatile long i, j;
    }

    public static class PC {
        public long i,i0, i1, i2, i3, i4, i5, i6, i7, j;
    }

    public static class PVC {
//        public volatile long i,i0, i1, i2, i3, i4, i5, i6, i7, j;
        public volatile long i,i0,i1, j; // i,j不能相邻, 中间至少加两个变量,
    }
}
